<template>
  <div>
    <el-input
      :placeholder="fld.placeholder ? fld.placeholder : '点击选择'"
      :value="text"
      :clearable="fld.clearable"
      @clear="handleClear"
      size="mini">
      <el-button slot="append" icon="el-icon-more" @click="dialogTableVisible=true" :disabled="fld.disabled" size="mini"></el-button>
    </el-input>
    <input type="hidden" :name='fld.name' :value="value"></input>
    <el-dialog
      :title="fld.title"
      :visible.sync="dialogTableVisible"
      append-to-body
      @open="handleOpen"
      ref="dialog"
      :width="width"
      >
      <comp-table
        :cols="columns"
        :action="fld.action"
        ref="table"
        height="290"
        @row-dblclick="handleSelect"
        >
        <!-- 左上角插槽-搜索 -->
        <template slot="leftTopSlot">
          <!-- <div style="width:100%;"> -->
            <!-- <el-input placeholder="关键字"  size="mini" v-model="key">
              <el-button slot="append" icon="el-icon-search" @click="handleSearch"></el-button>
            </el-input> -->
            <div v-for="(item,index) in searchItems" :key="index" style="width:180px;float:left; margin-right:5px;margin-bottom:5px;">
              <component
                :is="item.type"
                :fld="item"
                :ref="item.name"
                :value="searchConfig[item.name]"
                :placeholder="item.title"
                @input="searchConfig[item.name]=arguments[0]"
              ></component>
            </div>
            <el-button icon="el-icon-search" circle size="mini" type="primary" @click="handleSearch"></el-button>

          <!-- </div> -->
        </template>

        <!-- 左下角插槽-分页 -->
        <template slot="leftBottomSlot">
          <div style="float:left; margin-top:5px;" >
            <div style="float:left;">
              <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="[20,50, 100, 200]"
                :page-size="pagesize"
                layout="prev, pager, next"
                :total="total"
                background
              ></el-pagination>
            </div>
            <!-- 分页后的文字说明 -->
            <!--<span style="float:left;margin-top:9px;" v-html="textAfterPage"></span> -->
          </div>
        </template>
      </comp-table>

      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogTableVisible = false">取 消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script type="text/javascript">
  define(['vue','Common'],function(vue,Common){
    return vue.component('comp-popup-select',{
      components: {
        'comp-table' : resolve=>require(['_vue!pathComponent/comp-table'], resolve),
        'comp-text' : resolve=>require(['_vue!pathComponent/comp-text'], resolve),
        'comp-autocomplete' : resolve=>require(['_vue!pathComponent/comp-autocomplete'], resolve),
        'comp-calendar' : resolve=>require(['_vue!pathComponent/comp-calendar'], resolve),
        'comp-checkbox' : resolve=>require(['_vue!pathComponent/comp-checkbox'], resolve),
        'comp-checkbox-group' : resolve=>require(['_vue!pathComponent/comp-checkbox-group'], resolve),
        // 'comp-file' : resolve=>require(['_vue!pathComponent/comp-file'], resolve),
        'comp-select' : resolve=>require(['_vue!pathComponent/comp-select'], resolve),
        'comp-text-compose' : resolve=>require(['_vue!pathComponent/comp-text-compose'], resolve),
        // 'comp-popup-select' : resolve=>require(['_vue!pathComponent/comp-popup-select'], resolve),
      },
      props:['fld','value','display-text'],
      computed:{
        text:function(){
          if(this.value=='' || this.value==undefined) return '';
          var key = this.fld.displayRowKey || this.fld.displayKey;
          if(Common.isset(this.$attrs.row,key)) return this.$attrs.row[key]; 
          // var temp = this.$attrs.row ? this.$attrs.row[key] : '';
          // return temp || this.displayText;
          return this.displayText;
        }
      },
      watch : {
        // value(val,oldVal) {
        //   dump('value changed to ',val)
        // }
      //   //在选中不同子表记录时会触发这个变化
      //   'displayText':  {
      //     handler : function(newVal,oldVal) {
      //       // dump(`弹出选择控件${this.fld.name}.displayText change`,newVal,oldVal);
      //       this.text = newVal;
      //     }
      //   }
      },
      data:function(){
        return {
          columns: {
            'date':{'text':'日期','width':200},
            'name':{'text':'姓名','width':200},
            'address':{'text':'地址','width':300},
          },
          // rows: [{
          //   date: '2016-05-02',
          //   name: '王小虎',
          //   address: '上海市普陀区金沙江路 1518 弄'
          // }],
          multiSelect:this.fld.multiSelect,
          //获取数据的url
          action:this.fld.action,
          //参数:其中可能包括从open方法中传入的参数,搜索参数,分页参数
          params:{},
          //搜索关键字
          key:'',
          //弹窗选择列表记录中的字段名,表单提交时该字段的值会提交到后台,并作为外键进行保存
          rowKey:this.fld.rowKey ||'id',

          //需要回显在text中的弹窗列表字段,比如客户名称
          displayKey:this.fld.displayKey,
          //text中显示的默认值，
          //可能显式声明了display-text属性，
          //也可能需要显示记录中某个字段的值
          //text : this.displayText || this.$attrs.row[this.fld.displayKey],
          //对话框是否显示
          dialogTableVisible:false,
          //分页参数
          currentPage:1,
          pagesize:20,
          total:400,//记录总数
          width:this.fld.dialogWidth || "50%",
          //主从表模板中，字表记录会传入row的值
          // row : this.$attrs.row || {},
          searchItems : [],
          //搜索项的定义
          searchConfig : {},
        };
      },
      template: template,
      methods:{
        //设置displayText的值

        //以下事件没用了,都是在handelselect事件中处理了
        // handleModelInput :function(val){
        //   this.$emit("input", val);
        // },
        //dialog打开前的回调
        handleOpen :function(){
          var key = `${this.fld.name}:open`;
          if(this.$root.callbacks[key]) {
            this.$root.callbacks[key].apply(this,[this]);
          }
          //dom元素生成后,从服务器获取数据
          this.$nextTick(()=>{
            this.$refs.table.multiSelect = this.multiSelect;
            this._getRows();
          });
        },
        //通过ajax请求从服务器获得数据
        _getRows : function() {
          var url = this.action;
          if(url=='' || url==undefined) {
            alert('popup-select 组件未定义action参数');
            return false;
          }
          this.params.pagesize = this.pagesize;
          this.params.currentPage = this.currentPage;
          //将searchConfig中的值放入
          for(var k in this.searchConfig) {
            this.params[k] = this.searchConfig[k];
          }
          // this.params.key = this.key;
          // dump(this);
          // var param= {pagesize:this.pagesize,currentPage:this.currentPage};
          //var _this = this;
          this.$http.post(url, this.params)
          .then((response)=>{
            var cols = this._formatColumns(response.data.columns);
            var rows = this._formatRows(response.data.rows);
            this.total = response.data.total;
            this.$refs.table.columns = response.data.columns;
            this.$refs.table.rows = rows;
          })
          .catch(function (error) {
            console.error(error);
          });
        },
        //格式化表头定义
        _formatColumns : function(columns) {
          for(var key in columns) {
            if(typeof(columns[key])=='string') {
              columns[key] = {'text':columns[key],'width':80};
            }
          }
          return columns;
        },
        //格式化数据集
        _formatRows : function(rows) {
          //判断返回的记录集中是否存在rowKey字段,
          //如果存在构造虚拟的rowKey,否则返回时有错.
          if(rows.length>0) {
            if(rows[0][this.rowKey]==undefined) {
              console.warn(`后台返回的数据集中未包含${this.rowKey}字段,这可能导致确认回调时的错误!`);
              //构造虚拟的rowkey
              for(var i=0;rows[i];i++) {
                rows[i][this.rowKey] = i+1;
              }
            }
          }
          return rows;
        },
        //页数改变时触发
        handleSizeChange :function(size) {
          this.currentPage=1;
          this.pagesize=size;
          this._getRows();
        },
        handleCurrentChange : function(page) {
          this.currentPage=page;
          this._getRows();
        },
        //双击回调
        handleSelect : function(row,e){
          // debugger;
          var rowKey = this.fld.rowKey;
          if(!row.hasOwnProperty(rowKey)) {
            console.error(`选中的记录中未包含 ${rowKey} 字段`);
            return false;
          }
          //改变文本框中的值,文本框属于组建内的元素,这个元素的改变应该组件自己负责
          //而hidden控件绑定的是记录集中的字段,这个值的改变应该由父组件负责
          var key = this.fld.displayRowKey || this.fld.displayKey;
          var __k = typeof(key)=='object' ? key.popup : key;
          // dump('--------------',this.fld.displayKey);

          // this.text = row[__k];
          //不直接改变组件的属性，而是改变相关联的字表记录的字段，这样保持最大的联动性
          //不能直接赋值，如果直接赋值可能导致computed中的代码失效
          vue.set(this.$attrs.row,__k,row[this.fld.displayKey]);
          // dump(this.fld.displayKey);return;
          // return;
          // this.$attrs.row[this.fld.displayKey] = row[__k];

          //向外抛出事件,改变displayText所代表的子表记录的字段值
          //比如选择了一个客户，在主从表单中的字表记录中的客户列需要改变
          // this.$emit('displaytext-change',this.text);

          this.dialogTableVisible = false;
          this.$emit('input',row[rowKey]);
          var key = `${this.fld.name}:select`;
          if(this.$root.callbacks[key]) {
            this.$root.callbacks[key].apply(this,[row,e]);
          }
        },

        //点击搜索
        handleSearch : function() {
          this.currentPage=1;
          this._getRows();
        },

        //取消已选择结果
        handleClear : function() {
          // this.text='';
          vue.set(this.$attrs.row,this.fld.displayKey,'');
          // this.$attrs.row[this.fld.displayKey] = '';
          // this.row[this.fld.displayKey] = '';
          // if(this.$attrs.row) {
          //   this.$attrs.row[this.fld.displayKey] = '';
          // }
          // this.$emit('clear',`${this.fld.name}:clear`,this);
          this.$emit('input','');
        },

        //根据配置信息,返回所有需要构造的搜索控件
        //所有的搜索控件在Config/Searchitems_config.php中定义好了.
        setSearchItems : function(opt) {
          var maxSearchItem = 5;
          var i=0;
          for(var k in opt) {
            i++;
            if(i>maxSearchItem) {
              delete(opt[k]);
            }
          }
          if(i>maxSearchItem) {
            console.warn(`comp-popup-select控件(${this.fld.name})最多支持 ${maxSearchItem} 个搜索项`)
          }
          //确保opt只有3个
          this.searchConfig = opt;
          //从服务器获得高级搜索条目
          var url='?controller=searchitems&action=getcomps';
          //将this.searchitems转变成数组
          var temp=[]
          for(var key in opt) {
            var _temp = typeof(opt[key])=="object"&&opt[key].hasOwnProperty('value') ? opt[key] : {value:opt[key]};
            _temp.key = key;
            temp.push(_temp);
          }
          var params={items:temp};
          // dump(params);
          this.$http.post(url,params).then((res)=>{
            if(!res.data.success) {
              this.$notify.error({
                'title':'保存失败',
                'message':'response.data.success not found'
              });
              // dump(res);
              return false;
            }
            //开始处理返回的items
            var items = res.data.items;
            this.searchItems = items;
            // dump(this.searchItems);

            //根据服务器返回的字段定义,为this.params进行初始化
            items.forEach((item,i)=>{
              //不能直接进行设置,因为params中的变量和控件存在绑定关系,简单创建变量不能生成绑定关系,必须使用Vue.set来进行设置
              // this.params[item.name]='';
              vue.set(this.params,item.name,opt[item.name]||'');
            });

            this.$emit('on-mount',this);

          }).catch(function (error) {
            console.error(error);
            this.$notify.error({
              'title':'请求失败',
              'message':'请求失败,检查url或者其他设置'
            });
          });
        }
      },
      mounted:function(){
        if(!this.$attrs.row) {
          console.warn('comp-popup-select 必须定义row属性');
        }
        this.setSearchItems(this.fld.searchItems || {key:''});
      }
    });
  });
</script>
<style type="text/css">
  .el-dialog__body {padding: 0 20px 30px 20px;}
  .el-dialog__footer {padding: 10px 20px 5px 20px;}
</style>